home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / haeberli / libgutil / brush.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  8KB  |  433 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  *    brush -
  19.  *        draw geometric brushes for impression
  20.  *
  21.  *            Paul Haeberli - 1987
  22.  *
  23.  *    exports
  24.  *
  25.     void ssortho(xsize, ysize)
  26.     void ssdrawinit()
  27.     void ssdraw(ss)
  28.     void wrapssdraw(ss)
  29.     void ssblob(ss,x,y,xsize,ysize)
  30.     void ssline(x1,y1,x2,y2,width)        NOT IMPLEMENTED
  31.     void drawstroke(s)
  32.     void ssbrushobj(myobj)
  33.     void ssconesides(n)
  34.     void drawcone()
  35.     void tmrect(x0,y0,x1,y1)
  36.     void drawline(x0,y0,x1,y1)
  37.     void myc4f(c)
  38.     void mycpack(c)
  39.     void blendon( )
  40.     void blendoff( )
  41.     
  42.  *
  43.  */
  44. #include "math.h"
  45. #include "values.h"
  46. #include "gl.h"
  47. #include "ss.h"
  48. #include "texture.h"
  49. #include "obj.h"
  50. #include "gfxmach.h"
  51.  
  52. #define NBRISTLES    (3)
  53. #define WIDTH        (0.25)
  54.  
  55. float frand();
  56. static float tmxscale, tmyscale;
  57. static int vpxsize, vpysize;
  58. static int npnts = 25;
  59. static int sqnpnts = 5;
  60. static object *obj;
  61. static float posxscale = 1.0;
  62. static float posyscale = 1.0;
  63.  
  64. void drawstroke();
  65. void drawcone();
  66. void tmrect();
  67. void drawline();
  68. void mycpack();
  69. void blendon();
  70.  
  71. void ssortho(xsize, ysize)
  72. int xsize, ysize;
  73. {
  74.     float xmax, ymax;
  75.  
  76.     if(xsize>ysize) {
  77.     xmax = 1.0;
  78.     ymax = (float)ysize/xsize;
  79.     } else {
  80.     xmax = (float)xsize/ysize;
  81.     ymax = 1.0;
  82.     }
  83.     posxscale = xmax;
  84.     posyscale = ymax;
  85.     renderortho(0.0,xmax,0.0,ymax,-1.0,1.0);
  86.     ortho(0.0,xmax,0.0,ymax,-1.0,1.0);
  87.     blendon();
  88. }
  89.  
  90. void ssdrawinit()
  91. {
  92.     short x0, x1, y0, y1;
  93.  
  94.     getviewport(&x0,&x1,&y0,&y1);
  95.     vpxsize = x1-x0+1;
  96.     tmxscale = 1.0/vpxsize;
  97.     vpysize = y1-y0+1;
  98.     tmyscale = 1.0/vpysize;
  99.     npnts = 12.0*5.0*(vpxsize*vpxsize)/(1000.0*1000.0);
  100.     sqnpnts = sqrt((float)npnts)+0.5;
  101. }
  102.  
  103. void ssdraw(ss)
  104. sampleset *ss;
  105. {
  106.     sample *s; 
  107.  
  108.     ssdrawinit();
  109.     s = ss->head;
  110.     while(s) {
  111.     drawstroke(s);
  112.     s = s->next;
  113.     }
  114. }
  115.  
  116. void wrapssdraw(ss)
  117. sampleset *ss;
  118. {
  119.     int x, y;
  120.     sample *s; 
  121.  
  122.     ssdrawinit();
  123.     s = ss->head;
  124.     while(s) {
  125.         for(y=0; y<3; y++) {
  126.         for(x=0; x<3; x++) {
  127.                    pushmatrix();
  128.             translate(x-1.0,y-1.0,0.0);
  129.             drawstroke(s);
  130.                    popmatrix();
  131.         }
  132.         }
  133.     s = s->next;
  134.     }
  135. }
  136.  
  137. void ssblob(ss,x,y,xsize,ysize)
  138. sampleset *ss;
  139. float x, y, xsize, ysize;
  140. {
  141.     pushmatrix();
  142.     translate(x,y,0.0);
  143.     scale(xsize,ysize,1.0);
  144.     translate(-0.5,-0.5,0.0);
  145.     ssdraw(ss);
  146.     popmatrix();
  147. }
  148.  
  149. void ssline(x1,y1,x2,y2,width)
  150. {
  151. }
  152.  
  153. void drawstroke(s)
  154. sample *s;
  155. {
  156.     float currad;
  157.     float curdir;
  158.     float radscale, rad;
  159.     float by, ydelt;
  160.     int i;
  161.     float xpos, ypos;
  162.     int x, y, nb;
  163.  
  164.     pushmatrix();
  165.     translate(posxscale*(float)s->xpos/(float)POSSCALE,
  166.           posyscale*(float)s->ypos/(float)POSSCALE,0.0);
  167.     radscale = 2.0/768.0;
  168.     currad = radscale*s->SAMPLE_SIZE;
  169.     rad = currad/2.0;
  170.     i = s->SAMPLE_DIR;
  171.     curdir = (i*360.0)/256.0;
  172.     mycpack((s->a<<24)+(s->b<<16)+(s->g<<8)+(s->r<<0));
  173.     switch(s->SAMPLE_SHAPE) {
  174.     case CIRCLES:
  175.         fillcirc(0.0,0.0,rad/2.0);
  176.         break;
  177.     case SQUARES:
  178.         rot(curdir,'z');
  179.         fillrect(-rad/2.0,-rad/2.0,rad/2.0,rad/2.0); 
  180.         break;
  181.     case STROKES:
  182.         rot(curdir,'z');
  183.         fillrect(-rad,-rad/4.0,rad,rad/4.0); 
  184.         break;
  185.     case LONGSTROKES:
  186.         rot(curdir,'z');
  187.         fillrect(-rad,-rad/16.0,rad,rad/16.0); 
  188.         break;
  189.     case LINES:
  190.         rot(curdir,'z');
  191.         scale(rad,rad,1.0);
  192.         by = -WIDTH/2.0;
  193.         ydelt = (WIDTH)/(NBRISTLES-1);
  194.         for(i=0; i<NBRISTLES; i++) {
  195.         fillrect(-1.0/2.0+(frand()/2.0),by-ydelt/16.0,1.0/2.0+(frand()/2.0),by+ydelt/16.0);
  196.         by += ydelt;
  197.         }
  198.         break;
  199.     case SCATTER:
  200.         scale(rad,rad,1.0);
  201.         for(i=npnts; i--;) {
  202.         xpos = frand()-0.5;
  203.         ypos = frand()-0.5;
  204.         pnt2(xpos,ypos);
  205.         }
  206.         break;
  207.     case LONGSCATTER:
  208.         rot(curdir,'z');
  209.         scale(rad,rad,1.0);
  210.         for(i=npnts; i--;) {
  211.         xpos = 3.0*(frand()-0.5);
  212.         ypos = 0.25*(frand()-0.5);
  213.         pnt2(xpos,ypos);
  214.         }
  215.         break;
  216.     case SCATTERPOLY:
  217.         scale(rad,rad,1.0);
  218.         for(i=0; i<20; i++) {
  219.         xpos = frand()-0.5;
  220.         ypos = frand()-0.5;
  221.         fillrect(xpos-0.05,ypos-0.05,xpos+0.05,ypos+0.05);
  222.         }
  223.         break;
  224.       case CONE:
  225.         drawcone();
  226.         break;
  227.     case FINELINES:
  228.         rot(curdir,'z');
  229.         scale(rad,rad,1.0);
  230.         by = -WIDTH/2.0;
  231.         ydelt = (WIDTH)/(NBRISTLES-1);
  232.         for(i=0; i<NBRISTLES; i++) {
  233.         drawline(-1.0/2.0+(frand()/5.0),by,1.0/2.0+(frand()/5.0),by);
  234.         by += ydelt;
  235.         }
  236.         break;
  237.     case ONELINE:
  238.         rot(curdir,'z');
  239.         drawline(-rad,0.0,rad,0.0);
  240.         break;
  241.     case NEEDLEPOINT:
  242.         scale(1.2,1.2,1.0);
  243.         rot(-45.0,'z');
  244.         fillrect(-rad/5.0,-rad/2.0,rad/5.0,rad/2.0); 
  245.         break;
  246.     case TEXTUREMAP:
  247.         if(fasttm()) {
  248.         rot(curdir,'z');
  249.         tmrect(-rad,-rad/2.0,rad,rad/2.0);
  250.         }
  251.         break;
  252.     case MULTILINE:
  253.         rot(curdir,'z');
  254.         scale(2.0*rad/1.5,2.0*rad,1.0);
  255.         by = -WIDTH/2.0;
  256.         nb = 3.0*sqnpnts;
  257.         if(nb<1)
  258.         nb = 1;
  259.         by = -WIDTH/2.0;
  260.         ydelt = (WIDTH)/(nb-1);
  261.         for(i=0; i<nb; i++) {
  262.         drawline(-1.0/2.0+(frand()/5.0),by,1.0/2.0+(frand()/5.0),by);
  263.         by += ydelt;
  264.         }
  265.         break;
  266.     case MYOBJECT:
  267.         if(obj) {
  268.         rot(curdir,'z');
  269.         scale(rad,rad,1.0);
  270.         drawobj(obj);
  271.         }
  272.     }
  273.     popmatrix();
  274. }
  275.  
  276. #define PYRSIZE        (0.25)
  277. static float tricoord[3][3];
  278. static int firsted;
  279. static int nsides = 30;
  280.  
  281. void ssbrushobj(myobj)
  282. object *myobj;
  283. {
  284.     obj = myobj;
  285. }
  286.  
  287. void ssconesides(n)
  288. int n;
  289. {
  290.     nsides = n;
  291.     firsted = 0;
  292. }
  293.  
  294. void drawcone()
  295. {
  296.     int i;
  297.     int sc, r, g, b;
  298.  
  299.     if(!firsted) {
  300.     tricoord[0][0] = 0.0;
  301.     tricoord[0][1] = 0.0;
  302.     tricoord[0][2] = 1.0;
  303.     tricoord[1][0] = PYRSIZE*sin(0*(2*M_PI)/nsides);
  304.     tricoord[1][1] = PYRSIZE*cos(0*(2*M_PI)/nsides);
  305.     tricoord[1][2] = 0.0;
  306.     tricoord[2][0] = PYRSIZE*sin(1*(2*M_PI)/nsides);
  307.     tricoord[2][1] = PYRSIZE*cos(1*(2*M_PI)/nsides);
  308.     tricoord[2][2] = 0.0;
  309.     firsted = 1;
  310.     }
  311.     pushmatrix();
  312.     for(i=0; i<nsides; i++) {
  313.     bgnpolygon();
  314.     v3f(tricoord[0]);
  315.     v3f(tricoord[1]);
  316.     v3f(tricoord[2]);
  317.     endpolygon();
  318.     rot(360.0/nsides,'z');
  319.     }
  320.     popmatrix();
  321. }
  322.  
  323. static int tmfirsted;
  324.  
  325. void tmrect(x0,y0,x1,y1)
  326. float x0,y0,x1,y1;
  327. {
  328.     vect t, v;
  329.  
  330.     if(!tmfirsted) {
  331.     textureread("brush.rgba",1);
  332.     tmfirsted = 1;
  333.     }
  334.     settexture(1);
  335.     bgnpolygon();
  336.     t.x = 0.0;
  337.     t.y = 0.0;
  338.     myt2f(&t);
  339.     v.x = x0;
  340.     v.y = y0;
  341.     v2f((float *)&v);
  342.  
  343.     t.x = 1.0;
  344.     t.y = 0.0;
  345.     myt2f(&t);
  346.     v.x = x1;
  347.     v.y = y0;
  348.     v2f((float *)&v);
  349.  
  350.     t.x = 1.0;
  351.     t.y = 1.0;
  352.     myt2f(&t);
  353.     v.x = x1;
  354.     v.y = y1;
  355.     v2f((float *)&v);
  356.  
  357.     t.x = 0.0;
  358.     t.y = 1.0;
  359.     myt2f(&t);
  360.     v.x = x0;
  361.     v.y = y1;
  362.     v2f((float *)&v);
  363.  
  364.     endpolygon();
  365.     settexture(0);
  366. }
  367.  
  368. void drawline(x0,y0,x1,y1)
  369. float x0,y0,x1,y1;
  370. {
  371.     float v[2];
  372.  
  373.     bgnline();
  374.     v[0] = x0;
  375.     v[1] = y0;
  376.     v2f(v);
  377.     v[0] = x1;
  378.     v[1] = y1;
  379.     v2f(v);
  380.     endline();
  381. }
  382.  
  383. void myc4f(c)
  384. float *c;
  385. {
  386.     int r, g, b;
  387.  
  388.     if(gfxmachine() == MACH4D8) {
  389.     r = 255.9*c[0];
  390.     g = 255.9*c[1];
  391.     b = 255.9*c[2];
  392.     rgbi(r,g,b);
  393.     } else 
  394.     c4f(c);
  395. }
  396.  
  397. void mycpack(c)
  398. long c;
  399. {
  400.     int r, g, b, i;
  401.  
  402.     if(gfxmachine() == MACH4D8) {
  403.     r = (c>>0)&0xff;
  404.     g = (c>>8)&0xff;
  405.     b = (c>>16)&0xff;
  406.     i = rgbi(r,g,b);
  407.     } else 
  408.     cpack(c);
  409. }
  410.  
  411. void blendon( )
  412. {
  413.     int mach;
  414.  
  415.     subpixel(1);
  416.     mach = gfxmachine();
  417.     if(getgdesc(GD_BLEND) && getgdesc(GD_BITS_NORM_SNG_RED)>6) {
  418.     blendfunction(BF_SA,BF_MSA);
  419.     linesmooth(SML_ON);
  420.     }
  421. }
  422.  
  423. void blendoff()
  424. {
  425.     int mach;
  426.  
  427.     mach = gfxmachine();
  428.     if(getgdesc(GD_BLEND) && getgdesc(GD_BITS_NORM_SNG_RED)>6) {
  429.     blendfunction(BF_ONE,BF_ZERO);
  430.     linesmooth(SML_OFF);
  431.     }
  432. }
  433.